package com.bdqn.crm.config.shiro;
import com.bdqn.crm.pojo.Right;
import com.bdqn.crm.pojo.Role;
import com.bdqn.crm.pojo.User;
import com.bdqn.crm.service.RoleService;
import com.bdqn.crm.service.UserService;
import jakarta.annotation.Resource;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MyShiroRealm extends AuthorizingRealm {

        @Resource
        private UserService userService;
        @Resource
        private RoleService roleService;
        @Resource
        private StringRedisTemplate stringRedisTemplate;
        private String SHIRO_LOGIN_COUNT = "shiro_login_count_";
        private String SHIRO_IS_LOCK = "shiro_is_lock_";
        @Override
        protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
            System.out.println("调用 MyShiroRealm 的 doGetAuthenticationInfo 获取身份信息");
            UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
            String usrName = token.getUsername();
            //每次访问，登录次数加+1
            ValueOperations<String,String>operations= stringRedisTemplate.opsForValue();
            operations.increment(SHIRO_LOGIN_COUNT+usrName,1);
            stringRedisTemplate.delete(SHIRO_IS_LOCK+usrName);//清空登录计算
            if (Integer.parseInt(operations.get(SHIRO_LOGIN_COUNT))>5){
                operations.set(SHIRO_IS_LOCK+usrName,"LOCK");
                stringRedisTemplate.expire(SHIRO_IS_LOCK+usrName,1, TimeUnit.HOURS);
                stringRedisTemplate.delete(SHIRO_LOGIN_COUNT+usrName);
                throw new LockedAccountException();//账号锁定
            }
            if ("LOCK".equals(operations.get(SHIRO_IS_LOCK+usrName))) {
                throw new DisabledAccountException();//账号锁定0
            }
            User user = userService.getByUsrName(usrName);
            if (user == null) {
                throw new AuthenticationException();//账号错误
            }
            if (user.getUsrFlag() == null || user.getUsrFlag().intValue() == 0) {
                throw new LockedAccountException();//账号被禁用
            }
            // 修改这里，使用 getName() 方法获取 Realm 的名称，确保与设置 SecurityManager 时一致
            SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(
                    user,
                    user.getUsrPassword(),
                    ByteSource.Util.bytes("czkt"),
                    getName());
            return info;
        }
               /* @Override
            protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
            System.out.println("调用MyShiroRealm的doGetAuthorizationInfo获取权限信息");
            //获得权限信息
            User user = (User) principalCollection.getPrim**-aryPrincipal();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            return info;
            } */
        /* protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
            System.out.println("调用MyShiroRealm的doGetAuthorizationInfo获取权限信息");
            //获得权限信息
            User user = (User) principals.getPrimaryPrincipal();
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            //静态授权：授予主体相应的角色和权限
            info.addRole(user.getRole().getRoleName());
            info.addStringPermission("用户列表");
            if ("管理员".equals(user.getRole().getRoleName())) {
                info.addStringPermission("用户添加");
                info.addStringPermission("用户编辑");
                info.addStringPermission("用户删除");
            }
            return info;
            } */
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals)
    {
        System.out.println("调用MyShiroRealm.doGetAuthorizationInfo获取动态权限信息");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        User user = (User) principals.getPrimaryPrincipal();
        //Role role=user.getRole();
        Role role = roleService.findRoleByUser(user);
        if (role!=null){
            info.addRole(user.getRole().getRoleName());
            //Set<Right> rights=role.getRights();
            List<Right>rights= roleService.findRightsByRole(role);
            if(rights!=null && rights.size()>0){
                for (Right right:rights){
                    info.addStringPermission(right.getRightCode());
                }
            }
        }
        return info;
    }
    //清空当前认证用户权限缓存
    public void clearMyCachedAuthorizationInfo(){
        clearCachedAuthorizationInfo(SecurityUtils.getSubject().getPrincipals());
    }
    //清空所有的用户缓存
    public void clearAllCachedAuthorizationInfo() {
        if (this.isAuthenticationCachingEnabled()) {//权限缓存是否可用
            Cache<Object, AuthorizationInfo> cache = null;
            CacheManager cacheManager = this.getCacheManager();
            if (cacheManager != null) {
                cache = cacheManager.getCache(this.getAuthorizationCacheName());
            }
             if (cache != null) {
                cache.clear();
            }
        }
    }
}

